/*
# fetch	(zfetch@mail.ru)
#
*/

#include <types.h> 

void 
map_page_to_frame(page_t *, page_t *, page_t *, char);
void 
enable_paging(page_t);
//page_t *alloc_frame();



//Подготовить PDE или PTE и вернуть его адрес
page_t 
*prepare_page_dir()
{
	//kprintf("ppd\n");
	page_t *page_dir = (page_t *) allocFrame(1);
	uint32 i;
	for(i = 0; i < 1024; i++){
		//kprintf("ppd_i:%i\n", i);
		page_dir[i] = 0;
	}
	return page_dir;
}

//Включить страничную адресацию, для этого первые 4 мегабайта виртуальной памяти 
//отображаем в физическую (прямое отображение)
page_t * 
init_mm()
{
	//kprintf("aFFF\n");
	page_t *page_dir = prepare_page_dir();
	uint32 i, j;
	for(i = 0; i < 1024; i++){
		//kprintf("i:%i\n", i);
		map_page_to_frame(page_dir, (page_t *)(i*4096), (page_t *)(i*4096), 0x7);
		
	}
	//kprintf("2FFF\n");
	for(i = 0, j = 0xC0000; i < 1024 * 8; i++, j++){
		map_page_to_frame(page_dir, (page_t *)(j*4096), (page_t *)(i*4096), 0x7);
	}
	//kprintf("FFF\n");
	enable_paging((page_t)page_dir);
	//kprintf("FFF\n");
	return page_dir;
}

//Отобразить страницу в кадр
void 
map_page_to_frame(page_t *page_dir, page_t *page_addr, page_t *frame_addr, char flag)
{
	//kprintf("zFFF\n");
	page_t page_dir_index, page_table_index;
	page_t *page_table;
	//kprintf("%X\n", page_dir);
	
	page_dir_index   = (page_t) page_addr >> 22;
	//kprintf("%X\n", page_dir_index);
	
	page_table_index = ((page_t)page_addr >> 12) & 0x3FF;
	//kprintf("%X\n", page_table_index);
	
	page_table = (page_t *)page_dir[page_dir_index];
	//kprintf("%X\n", page_table);
	
	if(page_table == 0){
		page_table = (page_t *) allocFrame(1);
		kprintf(":1:");
	}else{
		page_table = (page_t *)((page_t)page_table & 0xFFFFF000);
	}
	//kprintf("0");
	page_dir[page_dir_index] = (page_t)page_table | flag;
	page_table[page_table_index] = (page_t)frame_addr | flag;
	//kprintf("zFFF\n");
}

/*
Подготовка:
1. Создать PDE
2. Вычисляем старшие 10 бит адреса
3.
*/

/*Включить страничную адресацию*/
void 
enable_paging(page_t page_dir){
	
	asm(".code32 \
	movl %0, %%cr3;"::"r"(page_dir):"%eax");
	
	asm(".code32 \
	mov %cr0, %eax;	\
 	bts	$31, %eax; 	\
	mov %eax, %cr0;");
	
	kprintf("Paging enabeling\n");
	
}

